#!/bin/bash

. /usr/voltaire/common.sh
[ -r /usr/voltaire/gs.conf ] && . /usr/voltaire/gs.conf

function make_pkey_network()
{
	nib1=$(echo $given_network|cut -f1 -d.)
	nib2=$(echo $given_network|cut -f2 -d.)
	nib3=$(echo $given_network|cut -f3 -d.)
	nib4=$(echo $given_network|cut -f4 -d.)
	pkey=$(echo $given_if|cut -s -f2 -d.)
	if [ -z $pkey ] ; then
		fatal "not a child interface. don't use pkey option"
	fi
	pkey=0x$pkey	
	low_pkey=$(($pkey&0x00ff))
	given_network=$nib1.$low_pkey.$nib3.$nib4
}


function choose_netscript()
{
	ib_if=$1
	if [ $show -ne 0 ]
	then
		netscript=$(tty)
		becho "Writing network configuration to standard output and not to file"
		return 0
	fi

	case "${linux_dist}" in
	redhat|suse)
		netscript=$netscript_dir/ifcfg-$ib_if
		;;
	*) 
		exec 2>/dev/tty
		becho  "Unsupported linux distribution ..."
		exit 1
		;;
	esac

	if [ -f $netscript ]
	then
		if [ $overwrite -eq 0 ]
		then
			becho "Configuration file $netscript already exists. Use option -overwrite to replace it"
			exit 1
		fi
	
		if [ $backup_netscript -eq 1 ]
		then
			now=$(date +%d.%B.%Y-%H:%M:%S)
			cp $netscript $netscript.backup.$now
			becho "Old configuration was backed up to $netscript.backup.$now"
		fi
		rm -f $netscript
	fi
}


function dhclient_set()
{
	ib_if=$1
	parent_ib_if=$(echo $ib_if|cut -f1 -d.)
	if [ -f /sys/class/net/$parent_ib_if/address ]
	then
		dhcp_clinet_id=ff:00:00:04:04:$(cat /sys/class/net/$parent_ib_if/address |cut -f5-20 -d:)
	else
		fatal interface $parent_ib_if does not exist
	fi
	
	dhcp_line="interface \"$ib_if\" { send dhcp-client-identifier $dhcp_clinet_id; }"
	if [ $show -ne 0 ]
	then
		becho "Writing DHCP configuration to stdout rather than to file"
		echo $dhcp_line
	else
		# add new line
		echo $dhcp_line >> /etc/dhclient.conf
	fi
}

	
function ib_dynamic_set()
{
	ib_if=$1
	ib_if_active=$2
	exec 2>/dev/null
	#copy the relevant file(s)
	case "${linux_dist}" in
	redhat)
		echo "DEVICE=$ib_if" 	>>$netscript
		if [ $ib_if_active -ne 0 ]
		then
			echo "ONBOOT=yes" 	>>$netscript
		else
			echo "ONBOOT=no" 	>>$netscript
		fi
		echo "BOOTPROTO=dhcp" 	>>$netscript
		   ;;
           suse)
		   echo "PRE_UP_SCRIPT=/etc/sysconfig/network/ifup-pre-ib" >> 		$netscript
		   echo "POST_DOWN_SCRIPT=/etc/sysconfig/network/ifdown-post-ib" >>	$netscript
		   echo "BOOTPROTO='dhcp'"	>> $netscript
		   ;;
           *) 
           exec 2>/dev/tty
	   becho  "Unsupported distribution ..."
	   exit 1
           ;;
       esac
       
       exec 2>/dev/tty
       if [ $show -eq 0 ] ; then
	       info wrote $ib_if configuration to $netscript
	       cat $netscript|xargs
       fi
       return 0

}
function ib_static_set() {
	ib_if=$1
	ib_ip=$2
	ib_network=$3
	ib_netmask=$4
	ib_bc=$5
	ib_mtu=$6
	ib_if_active=$7
       exec 2>/dev/null
       #copy the relevant file(s)
       case "${linux_dist}" in
           redhat)

		   echo "DEVICE=$ib_if" 	>> $netscript
		   if [[ $ib_if_active -ne 0 ]]; then
			echo "ONBOOT=yes" 	>> $netscript
		   else
			echo "ONBOOT=no" 	>> $netscript
		   fi
		   echo "BOOTPROTO=static" 	>> $netscript
		   echo "IPADDR=$ib_ip" 	>> $netscript
		   echo "NETWORK=$ib_network" 	>> $netscript
		   echo "NETMASK=$ib_netmask" 	>> $netscript
		   echo "BROADCAST=$ib_bc" 	>> $netscript
		   echo "MTU=$ib_mtu" 		>> $netscript
		   ;;
           suse)
		   echo "PRE_UP_SCRIPT=/etc/sysconfig/network/ifup-pre-ib" >> 		$netscript
		   echo "POST_DOWN_SCRIPT=/etc/sysconfig/network/ifdown-post-ib" >>	$netscript
		   echo "BOOTPROTO='static'"	>> $netscript
		   echo "STARTMODE='onboot'"	>> $netscript
		   echo "REMOTE_IPADDR=''"	>> $netscript
		   echo "WIRELESS='no'"		>> $netscript
		   echo "IPADDR=$ib_ip"  	>> $netscript
		   echo "NETWORK=$ib_network"	>> $netscript
		   echo "NETMASK=$ib_netmask" 	>> $netscript
		   echo "BROADCAST=$ib_bc" 	>> $netscript
		   echo "MTU=$ib_mtu" 		>> $netscript
		   ;;
           *) 
           exec 2>/dev/tty
	   becho  "Unsupported distribution ..."
	   exit 1
           ;;
       esac

       exec 2>/dev/tty
       if [ $show -eq 0 ] ; then
	       info wrote $ib_if configuration to $netscript
	       cat $netscript|xargs
       fi
       return 0

}

function get_eth {
	eth_if=$1
       	exec 2>/dev/null
	if [ -z $eth_if ] ; then
       		exec 2>/dev/tty
		return 1
	fi
	ifconfig $eth_if > /dev/null
	if [ $? -ne 0 ] ; then
       		exec 2>/dev/tty
		return 1
	fi

	eth_ip=$(ifconfig ${eth_if} 2>/dev/null | perl -ne 'print "$1\n"if/inet addr:\s*(\S+)/i')
	[ -z $eth_ip ] && return 1
        eth_nm=$(ifconfig ${eth_if} 2>/dev/null | perl -ne 'print "$1\n"if/mask:\s*(\S+)/i')
	[ -z $eth_nm ] && return 1
        eth_bc=$(ifconfig ${eth_if} 2>/dev/null | perl -ne 'print "$1\n"if/bcast:\s*(\S+)/i')
	[ -z $eth_bc ] && return 1
       	exec 2>/dev/tty
	return 0
}
function usage(){
	echo "usage: $(basename $0) <-network network> [-netmask netmask] [-usepkey] [-eth eth-if] [-ib ib-if] [-mtu mtu] [-os RH|SUSE] [-noactive] [-nocolor] [-show] [-overwrite] [-backup] [-dhcp ] [-static_ip static_ip_addr -static_bc broadcast_ip_addr]"
}

# ============================================================
# 			MAIN
# ============================================================
config_dhcp=0
config_active=1
overwrite=0
show=0
backup_netscript=0
start_if=0
use_pkey=0
while [[ ! -z "$1" ]] ; do
        case $1 in
                -overwrite)
			overwrite=1
                        shift
                ;;
                -backup)
			backup_netscript=1
                        shift
                ;;
                -dhcp)
			config_dhcp=1
                        shift
                ;;
                -usepkey)
			use_pkey=1
                        shift
                ;;
                -eth)
			given_eth=$2
                        shift
                        shift
                ;;
                -network)
			given_network=$2
                        shift
                        shift
                ;;
                -netmask)
			given_netmask=$2
                        shift
                        shift
                ;;
                -ib)
			given_if=$2
                        shift
                        shift
                ;;
                -mtu)
			given_mtu=$2
                        shift
                        shift
		;;
                -os)
			linux_dist=$2
                        shift
                        shift
                ;;
                -show)
			show=1
                        shift
                ;;
                -noactive)
			config_active=0
                        shift
                ;;
                -start)
			start_if=1
                        shift
                ;;
                -nocolor)
			disable_color_print
                        shift
                ;;
                -static_ip)
			given_static_ip=$2
                        shift
                        shift
                ;;
                -static_bc)
			given_static_bc=$2
                        shift
                        shift
                ;;
		-static_network)
			given_static_network=$2
                        shift
                        shift
                ;;
                *)
                        echo "unknown switch $1"
			usage
                        exit 1
                ;;
        esac
done

if [ -z $given_if ] ; then
	given_if=ib0
fi
parent_if=$(echo $given_if|cut -f1 -d.)
child_if=$(echo $given_if|cut -f2 -d. -s)
if [ ! -z $child_if ] ; then
	child_if=$(printf "%x" $((0x$child_if|0x8000)))
	given_if=$parent_if.$child_if
fi
choose_netscript $given_if

# remove the existing dhcp config, if any
sed '/interface "'${given_if}'"/d' -i /etc/dhclient.conf

if [ $config_dhcp -eq 1 ] ; then
	ib_dynamic_set ${given_if} ${config_active}
	dhclient_set   ${given_if}
else

	if [ -z $given_network ] && [ -z ${given_static_network} ] ; then
		fatal "no network was given. use option -network (or -static_network) or -dhcp"
	fi
	if [ ! -z $given_network ] ; then
		if [ $use_pkey -ne 0 ] ; then
			make_pkey_network
		fi
	fi
	if [ ! -z $given_static_network ] ; then
		given_network=$given_static_network 
	fi
	if [ -z $given_eth ] ; then
		given_eth=eth0
	fi
	get_eth $given_eth
	if [ $? -ne 0 ] ; then		
		fatal "bad interface $given_eth"
	fi
	if [ -z $given_mtu ] ; then
		if [ ! -z $ipoib_mtu ] ; then
			given_mtu=$ipoib_mtu
		else	
			given_mtu=2044
		fi
	fi
	if [ ! -z $given_netmask ] ; then
		eth_nm=$given_netmask
	fi
	
	if [ ! -z $given_static_ip ] && [ ! -z $given_static_bc ] ; then
		calc_ip=$given_static_ip
		calc_bc=$given_static_bc
	elif [ -z $given_static_ip ] && [ -z $given_static_bc ] ; then

		calc_ip=$(perl -e 'use Socket; $iaddr = inet_aton("'$eth_ip'"); $netmask = inet_aton("'$eth_nm'"); $newip = inet_aton("'$given_network'"); $newip= ($iaddr & ~$netmask) | ($newip & $netmask); $NIP=inet_ntoa($newip);print $NIP' )
		calc_bc=$(perl -e 'use Socket; $iaddr = inet_aton("'$eth_bc'"); $netmask = inet_aton("'$eth_nm'"); $newip = inet_aton("'$given_network'"); $newip= ($iaddr & ~$netmask) | ($newip & $netmask); $NIP=inet_ntoa($newip);print $NIP' )
	else
                echo "Both static_ip and static_bc should be defined in order to get a static configuration."
		usage
                exit 1
	fi



	ib_static_set $given_if $calc_ip $given_network $eth_nm $calc_bc $given_mtu $config_active
fi
	
if [ $start_if -eq 1 ] ; then
	ifconfig $given_if|grep UP
	if [ $? -eq 0 ] ; then
		ifdown $given_if
	fi
	(ifup $given_if; if (which ifrenew &> /dev/null) ; then ifrenew $given_if ; fi)&
fi
		
exit 0
